/**
 * Copyright (C) 2017, hapjs.org. All rights reserved.
 */

import path from 'path'
import fs from 'fs'
import os from 'os'

import chalk from 'chalk'
import qrTerminal from 'qrcode-terminal'

/**
 * 创建任意深度的路径的文件夹
 * @param dirname
 * @returns {boolean}
 */
export function mkdirsSync (dirname) {
  if (fs.existsSync(dirname)) {
    return true
  }
  else {
    if (mkdirsSync(path.dirname(dirname))) {
      fs.mkdirSync(dirname)
      return true
    }
  }
}

const logLevelMap = {}

function prependLevel (levelName, args) {
  !logLevelMap[levelName] && ((levelNameInner) => {
    const logLevel = levelNameInner.toUpperCase().substr(0, 4)
    logLevel.paddEnd && logLevel.paddEnd(4)
    logLevelMap[levelName] = logLevel
  })(levelName)

  if (typeof args[0] === 'string' && args[0].length > 1 && args[0][0] !== '[') {
    args[0] = `[${logLevelMap[levelName]}] ${args[0]}`
  }
}

/**
 * 带颜色的info, log, warn, error, trace的输出工具函数
 */
export const colorconsole = {
  trace (...args) {
    prependLevel(`trace`, args)
    console.trace(...args)
  },
  log (...args) {
    prependLevel(`log`, args)
    console.log(chalk.green(...args))
  },
  info (...args) {
    prependLevel(`info`, args)
    console.info(chalk.green(...args))
  },
  warn (...args) {
    prependLevel(`warn`, args)
    console.warn(chalk.yellow.bold(...args))
  },
  error (...args) {
    prependLevel(`error`, args)
    console.error(chalk.red.bold(...args))
  },
  throw (...args) {
    throw new Error(chalk.red.bold(...args))
  }
}

/**
 * 获取服务器端的IP
 */
export function getIPv4IPAddress () {
  const ifaces = os.networkInterfaces()
  let result

  for (const prop in ifaces) {
    if (Object.prototype.hasOwnProperty.call(ifaces, prop)) {
      const iface = ifaces[prop]

      iface.every((eachAlias, j, all) => {
        if (eachAlias.family === 'IPv4' && !eachAlias.internal && eachAlias.address !== '127.0.0.1') {
          result = eachAlias
          return false
        }
        return true
      })

      if (result !== void 0) {
        break
      }
    }
  }

  return result && result.address
}

/**
 * 获取客户端ip
 * @param req node Http IncomingRequest Object
 * @returns {any|*|string}
 */
export function getClientIPAddress (req) {
  const ip = req.headers['x-forwarded-for'] ||
    req.connection && req.connection.remoteAddress ||
    req.socket && req.socket.remoteAddress ||
    req.connection && req.connection.socket && req.connection.socket.remoteAddress

  return stripPrefixForIPV4MappedIPV6Address(ip)
}

/**
 * 检测可能是IpV4-mapped IpV6 格式的ip
 * - https://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses
 *
 * @param ip  IpV4-mapped IpV6 string
 * @returns {*}
 */
export function stripPrefixForIPV4MappedIPV6Address (ip) {
  if (/^::.{0,4}:(\d{1,3}\.){3}\d{1,3}/.test(ip)) {
    ip = ip.replace(/^.*:/, '')
  }
  return ip
}

/**
 * 命令行输出二维码
 * @param text
 */
export function outputQRCodeOnTerminal (text) {
  console.info(``)
  console.info(`生成HTTP服务器的二维码: ${text}`)
  qrTerminal.generate(text, { small: true })
}

/**
 * 遍历目录文件 同步方法
 * @param dir
 * @param files 收集的文件列表
 * @param isInWhiteListFilter 判断文件是否处于白名单的回调函数
 */
export function traverseDirSync (dir, files, isInWhiteListFilter) {
  const list = fs.readdirSync(dir)
  list.forEach(function (file) {
    file = path.join(dir, file)
    const stat = fs.statSync(file)
    if (stat && stat.isDirectory()) {
      traverseDirSync(file, files, isInWhiteListFilter)
    }
    else {
      if (typeof isInWhiteListFilter === 'function' && !isInWhiteListFilter(file) || typeof isInWhiteListFilter !== 'function') {
        files.push(file)
      }
    }
  })
}
